#!/bin/sh
# Bug reports and comments to Igor.Ermolaev@intel.com
base=$(dirname $(readlink -f ${BASH_SOURCE[0]:-$0}))
if [ "$1" == -pinlit2 ] || [ "$1" == -record ] || [ "$1" == -warmup ];then action=$1;shift; else action=-record; fi
if [ $action == -warmup ];then
   factor=${1:-1.02}
else
   if [[ "$1" =~ ^[0-9BMK]+-[0-9BMK]+$ ]];then
      bottom=${1%-*}
      length=${1#*-}
      shift
   else
      if [ $action == -pinlit2 ];then
         bottom=30M
         length=100M
      else
         bottom=20B
         length=30B
      fi
   fi
   bottom=${bottom//B/000000000};bottom=${bottom//M/000000};bottom=${bottom//K/000}
   length=${length//B/000000000};length=${length//M/000000};length=${length//K/000}
fi
global="$TRACING_SDK_SDE_MPI_ARGS"
log_type=${TRACING_SDK_LOG_TYPE:-pinball}

if [ -z "$TRACING_SDK_STRACE" ];then

comm=`mktemp $PWD/comm.XXXXXXXXXX`

save_IFS="$IFS";IFS='
';ranges=( `grep '   sde -'` );IFS="$save_IFS"

precond="$TRACING_SDK_GATHER_CND"
if [ -n "$precond" ] && [ "${precond:0:1}" == '?' ];then
   precond=${precond#?}
   if [ ! -r $precond ];then unset precond; fi
fi
if [ -n "$precond" ];then 
   start_cond=$($base/precond print "$precond")' '
fi
if [ -z "$TRACING_SDK_GATHER_TID" ];then
   ftid=''
   mt_bhvr=detect
else
   ftid=${TRACING_SDK_GATHER_TID%%+*}
   if [ ${TRACING_SDK_GATHER_TID#*+} == all ];then mt_bhvr=force_mt; else mt_bhvr=force_st; fi
   if [ $ftid == auto ];then ftid=''; fi
fi
if [ $mt_bhvr == force_mt ];then mt_mode=' -mt'; else mt_mode=''; fi
if [ -n "$TRACING_SDK_GATHER_SCNT" ];then
   skpF=${TRACING_SDK_GATHER_SCNT##*/}
   if [ "$skpF" == "$TRACING_SDK_GATHER_SCNT" ];then 
      skpF=''
   else
      skpF=${skpF//B/000000000};skpF=${skpF//M/000000};skpF=${skpF//K/000}
   fi
   cntF=${TRACING_SDK_GATHER_SCNT%%/*}
   selF=${cntF##*[0-9]}
   if [ -z "$selF" ];then selF=L; fi
   cntF=${cntF%%[^0-9]*}
fi
if [ -n "$TRACING_SDK_GATHER_CNT" ];then
   selL=${TRACING_SDK_GATHER_CNT##*[0-9]}
   if [ -z "$selL" ];then selL=L; fi
fi
for template in "${ranges[@]}";do
   template=${template#   sde };template=${template%' -- $@'}
   re='-start-address\s+0x[0-9a-fA-F]+:[0-9]+';if [[ $template =~ $re ]];then skip_loop=true;   else skip_loop=false; fi
   re='-stop-address\s+0x[0-9a-fA-F]+:[0-9]+'; if [[ $template =~ $re ]];then whole_loop=false; else whole_loop=true; fi
   if [ -n "$TRACING_SDK_GATHER_SCNT" ];then
      if [ $selF == L ];then
         if [ $skip_loop == false ];then continue; fi
      else
         if [ $skip_loop == true  ];then continue; fi
      fi
      skip_cnt=$cntF
   else
      if [ $skip_loop == true ];then continue; fi
      skip_cnt=''
   fi
   if [ -n "$TRACING_SDK_GATHER_CNT" ];then
      if [ $selL == L ];then
         if [ $whole_loop == false ];then continue; fi
      else
         if [ $whole_loop == true  ];then continue; fi
      fi
      count=${TRACING_SDK_GATHER_CNT%%[^0-9]*}
   else
      count=1
   fi
   template=`echo $template|sed -e 's/-length\s\+[0-9]\+/-length \$length/' -e 's/\(-\(start\|stop\)-address\s\+0x[0-9a-fA-F]\+\)\(:[0-9]\+\)\?/\$\2_cond\1\$\2_scnt/g'`
   template=${template/-pinlit/$action};template=${template/ -trace-mt/\$mt_mode}
   start_scnt=${skip_cnt:+:$skip_cnt}
   eval range=(`echo $template|sed -n 's/^.*-start-address\s\+0x0*\([0-9a-fA-F]\+\).*-stop-address\s\+0x0*\([0-9a-fA-F]\+\).*$/"\1" "\2"/p'`)
   if [ -z "${range[0]}" ];then continue; fi
   if [ $# -eq 0 ];then
      eval r=\"$template\"
      echo;echo '   sde '$r' -- $@';echo
      unset TRACING_SDK_STRACE
      break
   fi
   if [ "${range[0]}" != "$prv_start" ] || [ -z "$tid" ] || [ -z "$pinball" ];then
      tid="$ftid"
      if [ -z "$tid" ];then
         save_length=$length;length=$((bottom/2+length/2));mt_mode=''
            eval r=\"$template\"
         length=$save_length
         r=`echo $r|sed 's/-stop-address\s\+0x[0-9a-fA-F]\+\s*//'`;r=${r/$action/-mix}
         TRACING_SDK_SDE_MPI_ARGS="$r -store-env -comm-channel $comm"${global:+ $global} "$@"
         dir=`tail -n 1 $comm`
         if [ -z "$dir" ];then
            echo;echo Error: Communication channel is broken;echo;break
         fi
         pinball="$dir/rgn.pinball"
         if [ ! -d "$pinball" ];then
            echo;echo Error: Application didn\'t run;echo;break
         fi
         result=`find "$pinball" -name sde-mix-out.txt -exec grep -m 1 -qi 'Start counting for tid' {} \; -exec grep -m 1 -qi 'Exiting due to -early-out' {} \; -print|tail -n 1`
         if [ -n "$result" ];then
            tid=`grep -m 1 -i 'Start counting for tid' "$result"|awk '{print $6}'`
         else
            echo
            echo Error: Region of interest hasn\'t been reached
            if [ -n "$TRACING_SDK_GATHER_SCNT" ];then
            echo '       'Try to reduce TRACING_SDK_GATHER_SCNT
            fi
            echo
            break
         fi
         if [ -z "$tid" ];then
            tid=0
            echo
            echo Warning: Can\'t find TID automatically, will use 0
            echo '        'You can override this by using TRACING_SDK_GATHER_TID=N\[+all\]
            echo
            if [ $mt_bhvr == force_mt ];then mt_mode=' -mt'; else mt_mode=''; fi
         else
            if [ $mt_bhvr != force_mt ] && ( [ $mt_bhvr == force_st ] || [ `grep -i '\(Start\|Stop\) counting for tid' "$result"|awk '{print $6}'|sort -u|wc -l` -lt 2 ] );then
               mt_mode=''
            else
               mt_mode=' -mt'
               tid=`grep -i 'Start counting for tid' "$result"|awk 'END{print $6}'`
               if [ $mt_bhvr != force_mt ];then
               echo
               echo Remark: More than 1 thread reached hot-spot, MT coLIT trace will be collected
               echo '        'You can override this by using TRACING_SDK_GATHER_TID=N\|auto
               echo
               fi
            fi
         fi
         $base/get_prf $(dirname "$result") -profile $(dirname "$result")
      fi
      if [ -n "$skpF" ];then
         eval r=\"$template\"
         r=`echo $r|sed -e 's/-stop-address\s\+0x[0-9a-fA-F]\+\s*//' -e 's/-length\s\+[0-9]\+\s*//' -e 's/\(^\|\s\)-start-address\s/\1-stop-address /'`;r=${r/$action/-icount}
         TRACING_SDK_SDE_MPI_ARGS="$r -tid $tid -store-env -comm-channel $comm"${global:+ $global} "$@"
         dir=( `tail -n 1 $comm` )
         if [ -z "$dir" ];then
            echo;echo Error: Communication channel is broken;echo;break
         fi
         ofs=`grep '$$ TID: '$tid' ICOUNT:' -i $dir/sde-icount.txt|awk 'END{print $NF}'`
         if [ `echo $ofs\<$skpF|bc` -eq 1 ];then
            echo
            echo Error: Offset to hot spot \($ofs\) is smaller than minimal ICOUNT \(${TRACING_SDK_GATHER_SCNT##*/}\)
            echo '       'Reduce minimal ICOUNT or increase TRACING_SDK_GATHER_SCNT by ~`echo "scale=1;t=$skpF/$ofs;if(t<1.1) 1.1 else t"|bc`X
            echo
            break
         fi
         skpF=''
      fi
      save_length=$length;((length*=2))
         eval r=\"$template\"
      length=$save_length
      r=`echo $r|sed 's/-stop-address\s\+0x[0-9a-fA-F]\+\s*//'`
      if [ $log_type == pinball ];then r=${r/$action/-record}; fi
      TRACING_SDK_SDE_MPI_ARGS="$r -tid $tid -store-env -comm-channel $comm"${global:+ $global} "$@"
      dir=`tail -n 1 $comm`
      if [ -z "$dir" ];then
         echo;echo Error: Communication channel is broken;echo;break
      fi
      pinball="$dir/rgn.pinball"
      if [ ! -d "$pinball" ];then
         echo;echo Error: Application didn\'t run;echo;break
      fi
      prv_start="${range[0]}"
   fi
   result=`find "$pinball" \( -name '*.'$tid'.result' -o -name '*.global.log' \) -exec grep -m 1 -q '\-control' {} \; \! -exec grep -m 1 -q '^inscount: 18446744073709551615$' {} \; \! -exec grep -m 1 -q '^num_threads_started: 0$' {} \; -print|tail -n 1|sed 's/\(\.[0-9]\+\)\?\.global\.log$/.'$tid'.result/'`
   if [ -z "$result" ];then
      if [ $whole_loop == true ] && [ -n "$TRACING_SDK_GATHER_SCNT" ];then
         echo
         echo   Warning: Due to TRACING_SDK_GATHER_SCNT the hot-spot hasn\'t
         echo '         'been reached. Trying to trace in iterations mode.
         echo '         'If the loop is innermost and is vectorized, use
         echo '         'TRACING_SDK_PROPAGATE_VFCT=F, to adjust number
         echo '         'of iterations in propagate command.
         echo
         continue
      else
         echo;echo Error: Region of interest hasn\'t been reached;echo;break
      fi
   fi
   if [ $(dirname "$result") != "$dir/rgn.itrace" ];then
      rm -rf "$dir/rgn.itrace";mv $(dirname "$result") "$dir/rgn.itrace";rm -rf "$pinball" "$dir/.mptrace"
      result="$dir/rgn.itrace/"$(basename "$result")
      pinball="$dir/rgn.itrace"
   fi
   size=`grep -m 1 -w inscount $result|awk '{print $2}'`
   if [ -z "$size" ] || ( [ $size -lt $length ] && [ -z "$TRACING_SDK_GATHER_CNT" ] && [ "$TRACING_SDK_GATHER_SCNT" != '1' ] );then
      if [ -n "$mt_mode" ] && [ -n "$size" ];then
         echo
         echo   Warning: Application terminated before end of region reached,
         echo '         'most likely to avoid injections.
         echo
      else
         echo
         echo   Error: Application terminated before end of region reached
         if [ -n "$TRACING_SDK_GATHER_SCNT" ];then
         echo '       'Try to reduce TRACING_SDK_GATHER_SCNT
         fi
         echo
         break
      fi
   fi

   #lid=`grep -i 'InitRegion called by thread' ${result%.*[0-9].result}.log.txt|tail -n 1|awk '{print $6}'`
   #if [ -n "$lid" ];then tid="$lid"; fi
   if [ -z "$mt_mode" ];then rdx=0; else rdx=$tid; fi
   basename=${result%.result};result=${basename%.*[0-9]}.$tid.result;if [ ! -f $basename.procinfo.xml ];then basename=${basename%.*[0-9]}; fi

   stream="$(dirname "$result")"/stream.txt
   save_mt_mode="$mt_mode";mt_mode='';save_start_cond="$start_cond";start_cond='';save_start_scnt="$start_scnt";start_scnt='';save_stop_scnt="$stop_scnt";stop_scnt=''
      eval r=\"$template\"
   mt_mode="$save_mt_mode";start_cond="$save_start_cond";start_scnt="$save_start_scnt";stop_scnt="$save_stop_scnt"
   r=`echo $r|sed 's/\s\+-\(start\|stop\)-address\s\+0x[0-9a-fA-F]\+//g'`;r=${r/$action/-pinlit2-replay64 $basename -itrace-execute -itrace-disasm 0}
   $base/flt_sde -itrace-file "^TID$rdx:" $r -tid $rdx|cat -n|grep -i "\s\(${range[0]:-NA}\|${range[1]:-NA}\)\$" >"$stream"
   
   count_adj=0
   save_mt_mode="$mt_mode";mt_mode='';save_start_cond="$start_cond";start_cond='';save_start_scnt="$start_scnt";start_scnt='';stop_scnt=''
      eval r=\"$template\"
   mt_mode="$save_mt_mode";start_cond="$save_start_cond";start_scnt="$save_start_scnt"
   r=`echo $r|sed -e 's/\s\+-start-address\s\+0x[0-9a-fA-F]\+//' -e 's/-stop-address\s\+0x[0-9a-fA-F]\+/-stop-address 0x'${range[0]}'/' -e 's/-length\s\+[0-9]\+\s*//'`;r=${r/$action/-pinlit2-replay64 $basename -icount}
   $base/run_sde $r -tid $rdx &>$basename.cnt.log
   skip_size=`grep -i '$$ TID: '$rdx' ICOUNT:' $basename.cnt.log|awk 'END{print $NF}'`
   if [ -z "$skip_size" ];then skip_size=$((2*length)); fi

   if [ -s "$stream" ];then
      strt_skip=`grep -m 1 -i "\s${range[0]}\$" "$stream"|awk '{print $1}'`
      if [ "${range[0]}" == "${range[1]}" ];then
         stop_skip=`grep -i "\s${range[1]}\$" "$stream"|awk 'NR==2{print $1}'`
      else
         stop_skip=`grep -m 1 -i "\s${range[1]}\$" "$stream"|awk '{print $1}'`
      fi
   else
      strt_skip=$skip_size
      save_mt_mode="$mt_mode";mt_mode='';save_start_cond="$start_cond";start_cond='';save_start_scnt="$start_scnt";start_scnt=''
         if [ "${range[0]}" == "${range[1]}" ];then stop_scnt=':2'; else stop_scnt=''; fi
         eval r=\"$template\"
      mt_mode="$save_mt_mode";start_cond="$save_start_cond";start_scnt="$save_start_scnt"
      r=`echo $r|sed -e 's/\s\+-start-address\s\+0x[0-9a-fA-F]\+//' -e 's/-length\s\+[0-9]\+\s*//'`;r=${r/$action/-pinlit2-replay64 $basename -icount}
      $base/run_sde $r -tid $rdx &>$basename.cnt.log
      stop_skip=`grep -i '$$ TID: '$rdx' ICOUNT:' $basename.cnt.log|awk 'END{print $NF}'`
   fi
   if [ -z "$strt_skip" ];then strt_skip=$((2*length)); fi
   if [ -z "$stop_skip" ];then stop_skip=$((2*length)); fi
   if [ $strt_skip -ge $stop_skip ];then size=$stop_skip; else size=$((stop_skip-strt_skip)); fi
   #if [ $skip_size -ge $((size/2)) ];then count_adj=1; fi
   if [ $skip_size -ge $stop_skip ];then count_adj=1; fi

   if [ -n "$TRACING_SDK_GATHER_CNT" ];then
      if [ -s "$stream" ];then
         size=`grep -i "\s${range[1]}\$" "$stream"|awk "NR==$count"'{print $1}'`
         ((count-=count_adj))
      else
         ((count-=count_adj))
         save_mt_mode="$mt_mode";mt_mode='';save_start_cond="$start_cond";start_cond='';save_start_scnt="$start_scnt";start_scnt=''
            if [ $count -eq 1 ];then stop_scnt=''; else stop_scnt=":$count"; fi
            eval r=\"$template\"
         mt_mode="$save_mt_mode";start_cond="$save_start_cond";start_scnt="$save_start_scnt"
         r=`echo $r|sed -e 's/\s\+-start-address\s\+0x[0-9a-fA-F]\+//' -e 's/-length\s\+[0-9]\+\s*//'`;r=${r/$action/-pinlit2-replay64 $basename -icount}
         $base/run_sde $r -tid $rdx &>$basename.cnt.log
         size=`grep -i '$$ TID: '$rdx' ICOUNT:' $basename.cnt.log|awk 'END{print $NF}'`
      fi
   elif [ -s "$stream" ];then
      rec=( `$base/get_icount $((bottom/2+length/2)) ${range[1]} <"$stream"` )
      count=${rec[0]};size=${rec[1]}
      if [ -n "$count" ];then
         if [ $count -le 1 ] && [ "${range[0]}" == "${range[1]}" ];then
            unset count size
         else
            ((count-=count_adj))
         fi
      fi
   else
      if [ "${range[0]}" == "${range[1]}" ];then size=$strt_skip; else size=$stop_skip; fi
   fi
   unset skip_size strt_skip stop_skip
   if [ -z "$size" ];then size=$((2*length)); fi
   if [ $size -gt $length ];then
      if [ -n "$TRACING_SDK_GATHER_CNT" ];then
         echo;echo Error: Specified count for hotspot produces too much instructions;echo;break
      fi
      if [ $whole_loop == true ];then
         echo
         echo   Remark: Hot loop is too big, switching to iterations mode.
         echo '        'If the loop is innermost and is vectorized, use
         echo '        'TRACING_SDK_PROPAGATE_VFCT=F, to adjust number
         echo '        'of iterations in propagate command.
         echo
         if [ -n "$TRACING_SDK_GATHER_SCNT" ] && [ $selF == L ];then
            echo;echo Error: Please, use TRACING_SDK_GATHER_SCNT=\<N\>I to skip iterations.;echo;break
         else
            continue
         fi
      else
         echo;echo Error: Iteration of hotspot is too big, skipping...;echo;break
      fi
   fi
   if [ -s "$stream" ];then
      if [ $count -eq 1 ];then stop_scnt=''; else stop_scnt=":$count"; fi
   fi
   if [ $size -lt $bottom ];then
      if [ -n "$TRACING_SDK_GATHER_CNT" ];then
         echo;echo Warning: Specified count for hotspot produces not enough instructions;echo
      else
         min_size=0;max_count=''
         if [ -s "$stream" ];then unset size; fi
         if [ $count_adj -lt $count ];then min_count=$count_adj; else min_count=0; fi
         while [ 1 ];do
            if [ -z "$size" ];then
               count=$count # SDE 8.7+ get_icount != -icount
            elif [ $size -eq 0 ];then
               min_count=$count;min_size=0
               ((count++))
            else
               if [ $size -lt $bottom ] || [ $size -ge $length ];then
                  if [ $size -lt 100 ] && [ $min_size -eq 0 ];then
                     min_count=$count;min_size=$size
                     ((count++))
                  #elif [ $size -eq $min_size ];then
                  #   max_count=$min_count;max_size=$min_size
                  #   if [ `echo "$min_count > 1"|bc` -eq 1 ];then min_count=0;min_size=0; fi
                  elif [ $size -lt $((2*length-100000)) ];then
                     if [ $size -lt $min_size ];then
                        echo;echo Error: Region of interest has inconsistent;echo '       'behaviour from run to run;echo;break 2
                     fi
                     ipl1=''
                     if [ "$count" == "$min_count" ];then
                        new_count=$count
                     else
                        ipl1=`echo "scale=20;t=( $size * $min_count - $min_size * $count ) / ( ( $count - 1 ) * $min_count - ( $min_count - 1 ) * $count );if( t < 0 ) 0 else t"|bc`
                        ipl0=`echo "scale=20;t=( $size - ( $count - 1 ) * $ipl1 ) / $count;if( t < 0 ) 0 else t"|bc`
                        new_count=`echo "scale=20;a=( $bottom + $ipl1 ) / ( $ipl0 + $ipl1 );scale=0;b=a/1;if ( b < a ) b + 1 else b"|bc`
                        #echo $ipl0 $ipl1 $new_count
                     fi
                     if [ $size -lt $bottom ];then
                        min_count=$count;min_size=$size
                     else
                        max_count=$count;max_size=$size
                     fi
                     if [ -n "$ipl1" ] && [ -n "$max_count" ] && [ `echo "$ipl1 < 0.00001"|bc` -eq 1 ];then
                        if [ `echo "scale=20;( $max_count - $min_count ) * $ipl0 < 0.1*$min_size"|bc` -eq 1 ];then
                           new_count=$min_count
                           max_count=`echo "$min_count+1"|bc`
                        fi
                     fi
                     #echo U $new_count
                     count=$new_count
                  else
                     new_count=`echo "$count - ( ( $size - $min_size - 1 ) + ( $size - $bottom ) * ( $count - $min_count ) ) / ( $size - $min_size )"|bc`
                     #echo D $new_count
                     max_count=$count;max_size=$size;count=$new_count
                  fi
                  if [ -n "$max_count" ] && [ `echo "$count >= $max_count"|bc` -eq 1 ];then
                     count=`echo "( $min_count + $max_count ) / 2"|bc`
                  fi
                  if [ `echo "$count < $min_count"|bc` -eq 1 ];then count="$min_count"; fi
                  if [ -n "$max_count" ] && [ `echo "$count > $max_count"|bc` -eq 1 ];then count="$max_count"; fi
                  if [ "$min_count" != "$max_count" ];then
                     if [ "$count" == "$min_count" ];then count=`echo "$min_count + 1"|bc`; fi
                     if [ "$count" == "$max_count" ];then count=`echo "$max_count - 1"|bc`; fi
                  fi
                  if [ `echo "$count > 9223372036854775807"|bc` -eq 1 ];then
                     echo
                     echo   Warning: MAX_INT64 reached, truncated.
                     echo '         'Is application execution time long enough\?
                     echo
                     max_count=9223372036854775808;count=9223372036854775807
                  fi
                  if [ "$count" == "$min_count" ] && [ $size -lt $length ];then
                     echo;echo Warning: Low number of instructions in trace;echo '         'To speed-up collection set low limit to: ~$((size-100000));echo;break
                  fi
               else
                  break
               fi
            fi
            save_mt_mode="$mt_mode";mt_mode='';save_start_cond="$start_cond";start_cond='';save_start_scnt="$start_scnt";start_scnt=''
               if [ $count -eq 1 ];then stop_scnt=''; else stop_scnt=":$count"; fi
               eval r=\"$template\"
            mt_mode="$save_mt_mode";start_cond="$save_start_cond";start_scnt="$save_start_scnt"
            r=`echo $r|sed -e 's/\s\+-start-address\s\+0x[0-9a-fA-F]\+//' -e 's/-length\s\+[0-9]\+\s*//'`;r=${r/$action/-pinlit2-replay64 $basename -icount}
            $base/run_sde $r -tid $rdx &>$basename.cnt.log
            size=`grep -i '$$ TID: '$rdx' ICOUNT:' $basename.cnt.log|awk 'END{print $NF}'`
            if [ -z "$size" ];then size=$((2*length)); fi
         done
      fi
   fi

   strace=$dir/rgn.strace
   strace_is_ok=false
   ibasename=$basename
   basename=$strace/pinlit64
   target=`echo $template|sed -n 's/^\(.\+\)\s\+'$action'.*$/\1/p'`
   rm -rf $strace
   for att in $(seq 1 10);do
      save_start_cond="$start_cond";start_cond='';save_start_scnt="$start_scnt";start_scnt=''
         eval r=\"$template\"
      start_cond="$save_start_cond";start_scnt="$save_start_scnt"
      r=`echo $r|sed -e 's/\s\+-start-address\s\+0x[0-9a-fA-F]\+//' -e 's/-length\s\+[0-9]\+\s*//'`;r=${r/$action/-pinlit2-replay64 $ibasename $action -log:basename $basename}
      $base/run_sde $r -tid $rdx
      if [ ! -f $basename.arch.xml ] && [ ! -f $basename.address ];then tbasename=$basename.$rdx; else tbasename=$basename; fi
      if [ `$base/run_sde${target:+ $target} -pinlit2-replay64 $tbasename -icount 2>&1|grep -i '$$ TID: 0 ICOUNT:'|wc -l` -gt 0 ];then
         strace_is_ok=true
         break
      fi
   done
   if [ $strace_is_ok == false ];then
      echo;echo Error: Relogging of region of interest failed;echo;break
   fi
   [ $rdx -eq $tid ] || rename $basename.$rdx $basename.$tid $basename.$rdx.*
   result=$basename.$tid.result
   if [ ! -f $basename.arch.xml ] && [ ! -f $basename.address ];then basename=$basename.$tid; fi

   ((count+=count_adj))
   if [ $count -eq 1 ];then stop_scnt=''; else stop_scnt=":$count"; fi
   eval r=\"$template\"
   TRACING_SDK_SDE_MPI_ARGS="$r -tid $tid -store-env"
   TRACING_SDK_STRACE=$strace
   echo;echo Trace gathered to: $TRACING_SDK_STRACE;echo;break
done

rm $comm

else
   result=`find "$TRACING_SDK_STRACE" \( -name '*.*[0-9].result' -o -name '*.global.log' \) -exec grep -m 1 -q '\-control\|-replay' {} \; \! -exec grep -m 1 -q '^inscount: 18446744073709551615$' {} \; \! -exec grep -m 1 -q '^num_threads_started: 0' {} \; -print|tail -n 1`
   if [ -z "$result" ];then
      echo;echo Error: Base log isn\'t found;echo;exit #'
   fi
   if [ `grep -w pin-command-line "$result"|grep -c 'focus[-_]thread'` -ne 0 ];then mt_mode=''; else mt_mode=' -mt'; fi
   if [ -z "$tid" ];then
      tid=`grep -w pin-command-line "$result"|grep -m 1 ':tid'|sed -n 's/^.*start:\(address\|icount\)[^, -]*:tid\([0-9]\+\).*$/\2/p'`
      if [ -z "$tid" ];then
         tid=`grep -w pin-command-line "$result"|grep -m 1 ':tid'|sed -n 's/^.*stop:\(address\|icount\)[^, -]*:tid\([0-9]\+\).*$/\2/p'`
      fi
   fi
   glb_start=`grep -w pin-command-line "$result"|grep -m 1 start|sed -n 's/^.*start:address:\(0x[0-9a-fA-F]\+\).*$/\1/p'`
   glb_stop=`grep -w pin-command-line "$result"|grep -m 1 stop|sed -n 's/^.*stop:address:\(0x[0-9a-fA-F]\+\).*:count\([0-9]\+\).*$/\1:\2/p'`
   idx=${tid:-0};result=`echo "$result"|sed 's/\(\.[0-9]\+\)\?\.\(result\|global\.log\)$/.'$idx'.result/'`
   if [ -z "$mt_mode" ];then rdx=0; else rdx=$idx; fi
   if [ -z "$basename" ];then
      basename=${result%.result};if [ ! -f $basename.arch.xml ] && [ ! -f $basename.address ];then basename=${basename%.*[0-9]}; fi
   fi
   if [ -z "$size" ];then
      size=`grep -m 1 -w inscount "$result"|awk '{print $2}'`
   fi
   if [ $action == -warmup ];then
      #scale=`grep -m 1 ^scale\: "$result"|sed 's/^.*:\s\+\(.\+\)$/\1/'`
      prolog=`grep -m 1 ^prolog\: "$result"|sed 's/^.*:\s\+\(.\+\)$/\1/'`
      hotspot=`grep -m 1 ^hotspot\: "$result"|sed 's/^.*:\s\+\(.\+\)$/\1/'`
      target=`grep -m 1 -w run_sde-command-line "$result"|sed 's/^.*:\s\+\(.\+\)\s\+-\(pinlit2\|record\).*$/\1/'`
      itrace="$TRACING_SDK_STRACE"
      ibasename="$basename"
      strace="${itrace/#rgn./wrm.}";strace="${itrace/#mid./wrm.}";if [ "$strace" == "$itrace" ];then strace="wrm.$itrace"; fi
      rm -rf "$strace";mkdir "$strace"
      TRACING_SDK_STRACE="$strace"
      basename=$(basename "${result%.*[0-9].result}")
      basename="$strace/${basename/#record/pinlit64}"
      if [ -z "$prolog" ];then
         addr=`grep -w pin-command-line "$result"|grep -m 1 start|sed -n 's/^.*start:address:\(0x[0-9a-fA-F]\+\).*$/\1/p'`
         if [ -z "$addr" ];then addr="$glb_start"; fi
         if [ -z "$addr" ];then
            addr=`grep -w run_sde-command-line "$result"|grep -m 1 start|sed -n 's/^.*start\S*\s\+\(0x[0-9a-fA-F]\+\).*$/\1/p'`
         fi
         prolog=`echo $size / $factor|bc`
         ofs=`$base/run_sde${target:+ $target} -pinlit2-replay64 $ibasename -pinplay:msgfile $basename.icount -icount -skip $lcat_size -stop-address $addr -tid $rdx 2>&1|grep '$$ TID: '$rdx' ICOUNT:' -i|awk 'END{print $NF}'`
         if [ -n "$ofs" ];then (( prolog += ofs )); fi
      fi
      if [ -z "$prolog" ];then
         eow=' -length 0'
         bor=''
      else
         rec=( `echo $prolog|sed 's/^\([0-9]\+\)+\(0x.\+\)$/\1 \2/p'` )
         if [ -n "${rec[1]}" ];then
            eow=" -waitfor-icount ${rec[0]} -stop-address ${rec[1]}"
            bor=" -waitfor-icount ${rec[0]} -start-address ${rec[1]}"
         else
            eow=" -length $prolog"
            bor=" -skip $prolog"
         fi
      fi
      if [ -n "$hotspot" ];then
         eor=" -length $hotspot"
      else
         addr=`grep -w pin-command-line "$result"|grep -m 1 stop|sed -n 's/^.*stop:address:\(0x[0-9a-fA-F]\+\).*:count\([0-9]\+\).*$/\1:\2/p'`
         if [ -z "$addr" ];then addr="$glb_stop"; fi
         if [ -z "$addr" ];then
            range=( `grep -w run_sde-command-line "$result"|grep -m 1 stop|sed -n 's/^.*-start-address\s\+0x0*\([0-9a-fA-F]\+\).*-stop-address\s\+0x0*\([0-9a-fA-F]\+\)\(:\([0-9]\+\)\)\?.*$/\1 \2 \4/p'` )
            if [ -n "${range[1]}" ];then
               scnt=${range[2]};if [ -z "$scnt" ];then scnt=1; fi
               #if [ -n "$scnt" ] && [ "${range[0]}" == "${range[1]}" ];then ((scnt--)); fi
               if [ $scnt -le 1 ];then scnt=''; fi
               addr=0x${range[1]}${scnt:+:$scnt}
            else
               addr=`grep -w run_sde-command-line "$result"|grep -m 1 stop|sed -n 's/^.*stop\S*\s\+\(0x[0-9a-fA-F]\+\(:[0-9]\+\)\?\).*$/\1/p'`
            fi
         fi
         if [ -n "$addr" ];then eor=" -stop-address $addr"; else eor=''; fi
      fi
      $base/run_sde${target:+ $target} -pinlit2-replay64 $ibasename -pinplay:msgfile $basename.mix -mix -tid $rdx$mt_mode -omix $strace/mix-out.wm.txt$eow
      $base/run_sde${target:+ $target} -pinlit2-replay64 $ibasename -log:LIT-warmup -tid $rdx$mt_mode -log:basename $basename$eow
      if [ ! -s "$ibasename.ptov" ];then
         ptov="$basename.warmup.ptov"
         if [ ! -f "$ptov" ];then ptov="$basename.$rdx.warmup.ptov"; fi
         if [ ! -s "$ptov" ];then unset ptov; fi
      fi
      $base/run_sde${target:+ $target} -pinlit2-replay64 $ibasename -pinlit2 -tid $rdx$mt_mode -log:basename $basename$bor$eor${ptov:+ -log:LIT-use-ptov "$ptov"}
      [ $rdx -eq $idx ] || rename $basename.$rdx $basename.$idx $basename.$rdx.*
      TRACING_SDK_SDE_MPI_ARGS="${target:+$target }-pinlit2-replay64 $ibasename -pinlit2 -tid $rdx$mt_mode -log:basename $basename$bor$eor"
      result=$basename.$idx.result
      if [ ! -f $basename.arch.xml ] && [ ! -f $basename.address ];then basename=$basename.$idx; fi
      size=`grep -m 1 -w inscount $result|awk '{print $2}'`
      [ -f $itrace/baseline.txt    ] && cp $itrace/baseline.txt    $strace/baseline.txt
      [ -f $itrace/coverage.sw.txt ] && cp $itrace/coverage.sw.txt $strace/coverage.sw.txt
      [ -f $itrace/groups.bl.txt   ] && cp $itrace/groups.bl.txt   $strace/groups.bl.txt
      [ -f $itrace/groups.sw.txt   ] && cp $itrace/groups.sw.txt   $strace/groups.sw.txt
      precond=`ls -t1 $itrace/precond.*.tbz2 2>/dev/null|head -n 1`
   fi
fi

if [ -n "$TRACING_SDK_STRACE" ];then
   strace=$TRACING_SDK_STRACE
   [ -n "$precond" ] && cp -u "$precond" $strace
   if [ $action == -warmup ];then
      [ -f $itrace/environment.txt ] && cp -u $itrace/environment.txt $strace/environment.txt
      [ -f $itrace/profile.csv ] && cp -u $itrace/profile.csv $strace/profile.csv
      [ -f $itrace/distrib.txt ] && cp -u $itrace/distrib.txt $strace/distrib.txt
      anchor=`ls -t1 $itrace/{loop,func,call,path}.*.s 2>/dev/null|head -n 1`
      if [ -f "$anchor" ];then
         cp -u $anchor $strace/$(basename $anchor)
         anchor=$strace/$(basename $anchor)
      fi
   else
      [ -f $strace/../environment.txt ] && mv -fu $strace/../environment.txt $strace/environment.txt
      [ -f profile.csv ] && cp -u profile.csv $strace/profile.csv
      [ ! -f $strace/baseline.txt ] && [ -f distrib.txt ] && cp -u distrib.txt $strace/distrib.txt
      anchor=`ls -t1 {loop,func,call,path}.*.s 2>/dev/null|head -n 1`
      if [ -f "$anchor" ];then
         cp -u $anchor $strace/$anchor
         anchor=$strace/$anchor
      fi
      target=`echo $TRACING_SDK_SDE_MPI_ARGS|sed 's/^\s*\(.\+\)\s\+\-\(pinlit2\|record\).*$/\1/'`
      #$base/run_sde${target:+ $target} -pinlit2-replay64 $basename -align-checker -align-checker-file $strace/algn-out.txt -clc -clc-out $strace/clc-out.txt -mix -tid $rdx$mt_mode -omix $strace/mix-out.txt -dyn-mask-profile -odyn-mask-profile $strace/msk-out.txt
   fi
   $base/run_sde${target:+ $target} -pinlit2-replay64 $basename -align-checker -align-checker-file $strace/algn-out.txt -clc -clc-out $strace/clc-out.txt -mix -tid $rdx$mt_mode -omix $strace/mix-out.txt -dyn-mask-profile -odyn-mask-profile $strace/msk-out.txt
   deps=`sed -n 's/^;\s\+dependencies:\s\+\(.\+\)/\1/p' $anchor|xargs echo`
   [ -n "$deps" ] && cp -u $deps $strace
   if [ -f $strace/mix-out.wm.txt ];then
      $base/coverage $basename.procinfo.xml <$strace/mix-out.wm.txt >$strace/coverage.wm.txt
   fi
   $base/coverage $basename.procinfo.xml <$strace/mix-out.txt >$strace/coverage.txt
   $base/reconstruct $strace/clc-out.txt $strace/algn-out.txt <$strace/mix-out.txt >$strace/flow.disasm
   if [ -x $base/python3 ];then python3=$base/python3; else python3=`which python3 2>/dev/null`; fi
   if [ -n "$python3" ];then $python3 -OO $base/analyze $strace/flow.disasm $rdx -loops all $basename.procinfo.xml >$strace/flow.s; fi
   if [ -s $strace/mix-out.txt ] && [ $(grep -c '^MAPADDR 0x' $strace/mix-out.txt) == '0' ];then
      $base/annotate -a2l $base/binutils/bin/addr2line $basename.procinfo.xml <$strace/mix-out.txt >$strace/ann-mix-out.txt 2>/dev/null
      [ -s $strace/ann-mix-out.txt ] && mv -fu $strace/ann-mix-out.txt $strace/mix-out.txt
   fi
   if [ -f $strace/coverage.sw.txt ];then coverage=$strace/coverage.sw.txt; else coverage=$strace/coverage.txt; fi
   if [ -n "$anchor" ];then
      func=`grep -m 1 -P ';---\s+.+' $anchor|sed 's/;---\s\+\([^: ]\+\).*/\1/'`
      if [ -z "$func" ];then
         func=`awk 'END{print $2}' $anchor`
         func=${func%%:[0-9]*}
      fi
   fi
   tfunc=`awk 'NR==1{print $4}' $coverage`
   func=${func:-$tfunc}
   if [ "$func" != "$tfunc" ];then
      echo;echo Warning: Focus function \($func\) isn\'t top trace function \($tfunc\);echo
   fi
   echo >>$result
   [ -z "$scale" ] || echo "scale: $scale" >>$result
#   [ -z "$prolog" ] || echo "prolog: $prolog" >>$result
#   [ -z "$hotspot" ] || echo "hotspot: $hotspot" >>$result
   if [ -f $strace/baseline.txt ];then
      $base/quality -baseline $strace/baseline.txt -full <$strace/coverage.txt >$strace/quality.txt
   elif [ -f $strace/profile.csv ];then
      $base/quality $strace/profile.csv -full <$strace/coverage.txt >$strace/quality.txt
   else
      echo;echo Warning: profile.csv isn\'t found, Quality can\'t be calculated.;echo #'
   fi
   if [ -f $strace/distrib.txt ];then
      $base/coverage $basename.procinfo.xml $strace/distrib.txt <$strace/mix-out.txt >$strace/groups.txt
   elif [ -f $strace/groups.bl.txt ];then
      $base/quality -baseline $strace/groups.bl.txt -full <$strace/coverage.txt >$strace/groups.txt
   fi
   if [ -f $strace/quality.txt ];then
      mv -f $strace/quality.txt $strace/coverage.txt
      quality=`grep -m 1 'Quality:' $strace/coverage.txt|awk '{print $2}'`
      if [ `echo ${quality%\%}'<33.33'|bc` -eq 1 ];then
         echo;echo Warning: Quality of the trace \($quality\) less than 33.33%.;echo
      fi
   fi
   if [ -f $strace/coverage.txt ];then
      dpf=`$base/etc/flop $strace/mix-out.txt|grep '^Unmasked'|grep DP|awk '{print $(NF-1)}'`
      spf=`$base/etc/flop $strace/mix-out.txt|grep '^Unmasked'|grep SP|awk '{print $(NF-1)}'`
      echo >>$strace/coverage.txt
      echo "DP GFLOP: $dpf" >>$strace/coverage.txt
      echo "SP GFLOP: $spf" >>$strace/coverage.txt
      if [ -s $strace/msk-out.txt ];then
         dpfa=`$base/etc/flop $strace/mix-out.txt $strace/msk-out.txt|grep Masked|grep DP|awk '{print $(NF-1)}'`
         spfa=`$base/etc/flop $strace/mix-out.txt $strace/msk-out.txt|grep Masked|grep SP|awk '{print $(NF-1)}'`
         if [ "$dpf" != "$dpfa" ] || [ "$spf" != "$spfa" ];then
            echo >>$strace/coverage.txt
            echo "DP GFLOP': $dpfa" >>$strace/coverage.txt
            echo "SP GFLOP': $spfa" >>$strace/coverage.txt
         fi
      fi
   fi
   if [ "${TRACING_SDK_STRACE_TYPE##*+}" != nomfp ];then
      mfpname=`echo $basename|sed 's/\.[0-9]\+$//'`.mfp
      $base/run_sde${target:+ $target} -pinlit2-replay64 $basename -log:LIT-warmup -tid $rdx$mt_mode -log:basename $mfpname
      [ -f $mfpname.$rdx.tzcat.gz ] && rename $mfpname.$rdx $basename.mfp $mfpname.$rdx.*
      if [ -x $base/etc/compresslt ];then
         if [ -f $strace/coverage.txt ];then
            echo >>$strace/coverage.txt
            $base/etc/compresslt $basename.mfp.tzcat.gz|$base/etc/mfp >>$strace/coverage.txt
         fi
         if [ -f $strace/coverage.wm.txt ];then
            mfp=`mktemp $PWD/mfp.XXXXXXXXXX`
            $base/etc/compresslt $basename.mfp.tzcat.gz|$base/etc/mfp -d >$mfp
            echo >>$strace/coverage.wm.txt
            $base/etc/compresslt $basename.tzcat.gz|$base/etc/mfp $mfp >>$strace/coverage.wm.txt
            rm $mfp
         fi
      fi
   fi
   $base/etc/run_sniper${target:+ $target} $basename.sift $strace -clear_stats 0 --preload-beg-end
   if [ -s "$strace/sim.out" ];then
      scpi=`grep -i 'IPC' "$strace/sim.out"|awk 'NR==1{printf "%.3f",1/$3}'`
      if [ -n "$scpi" ];then
         einstrs=`grep -i 'eInstrs' $strace/groups.txt|awk 'NR==1{print $2}'`
         if [ -n "$einstrs" ];then
            tcpi0=`grep -i 'tCPI' $strace/groups.bl.txt|awk 'NR==1{print $3}'`
            scpi0=`grep -i 'sCPI' $strace/groups.bl.txt|awk 'NR==1{print $3}'`
            pcpi0=`grep -i 'pCPI' $strace/groups.bl.txt|awk 'NR==1{print $3}'`
            if [ -n "$tcpi0" ] && [ -n "$scpi0" ] && [ -n "$pcpi0" ];then
               tcpi=`echo "scale=3;$scpi*$tcpi0/$scpi0"|bc`;tcpi="${tcpi/#./0.}"
               ecpi=`echo "scale=3;$scpi*$pcpi0/$scpi0"|bc`;ecpi="${ecpi/#./0.}"
               ecycles=`echo "scale=0;$einstrs*$ecpi/1"|bc`
               sed 's/^\(eInstrs.*\)$/\1\neCycles: '"$ecycles"'\n\ntCPI   : '"$tcpi"'\nsCPI   : '"$scpi"'\neCPI   : '"$ecpi"'/' "$strace/groups.txt" >"$strace/groups.upd.txt"
            fi
         else
            sed 's/^\(tCPI.*\)$/\1\nsCPI   : '"$scpi"'/' "$strace/groups.txt" >"$strace/groups.upd.txt"
         fi
         if [ -s "$strace/groups.upd.txt" ];then rm -f "$strace/groups.txt";mv "$strace/groups.upd.txt" "$strace/groups.txt"; fi 
      fi
   fi
   echo "run_sde-command-line: $TRACING_SDK_SDE_MPI_ARGS"|sed 's/\s\+-comm-channel\s\+[^ ]\+.*$//' >>$result
fi
